//
//  XPApplication.swift
//  PPApp
//
//  Created by xiaopin on 2024/2/28.
//

import UIKit
import KeychainSwift

/// 当前应用对象
@objcMembers
class XPApplication: NSObject {

    //MARK: 单例写法
    static let shared = XPApplication()
    
    private override init(){}
    
    //MARK: 当前网络、定位信息
    /// 当前网络
    var netEnv:NetEnv = .unavailable
    
    /// 当前定位信息
    var locationInfo:XPLocationModel?
    
    /// 当前城市
    var currentCityId:String?
    var currentCity:String?
    var currentCity_ShortName:String?
    
    //MARK: 主题模式
    /// 主题模式：跟随系统，浅色模式，深色模式
    var themeMode: ThemeMode {
        get {
            if let str = UserDefaults.standard.value(forKey: pp_const_thememode){
                return ThemeMode(rawValue: str as! String)!
            }
            return .default
        }
        set {
            UserDefaults.standard.set(newValue.rawValue, forKey: pp_const_thememode)
            NotificationCenter.default.post(name: .xpfThemeModeChanged, object: nil)
        }
    }
    
    /// 是否已经同意了隐私条款
    var isAgreedPrivacy:Bool {
        get{
            guard let value = UserDefaults.standard.object(forKey: pp_const_isAgreedPrivacy) as? Bool  else { return false }
            return value
        }
        
        set{
            UserDefaults.standard.set(newValue, forKey: pp_const_isAgreedPrivacy)
        }
    }
    
    //MARK: 应用配置
    private var _appConfig:XPAppConfig?
    /// 应用配置
    var appConfig:XPAppConfig?{
        get {
            if let config = _appConfig { return config }
            guard let dict = XPSandbox.shared.unarchiveObject(mtArchiveKey_AppConifg) as? [String:Any] else{ return nil}
            return XPAppConfig.deserialize(from: dict)
        }
        set{
            _appConfig = newValue
        }
    }
    /// 应用AppStore信息
    var appStoreInfo:XPAppStoreInfo?
    
    //MARK: 应用支持的语言
    /// 当前应用语言：en,en-US,zh-Hans-CN
    var language:String {
        get{
            var retValue = "en"
            //获取系统语言，且语言包有配置
            if let systemLanguages = UserDefaults.standard.value(forKey: "AppleLanguages") as? [String], let systemLanguage = systemLanguages.first {
                //PPLog("当前系统语言：\(systemLanguage)")
                //if languages?.contains(where: {$0.language_code == systemLanguage}) == true {
                //    retValue = systemLanguage
                //}
            }
            
            //当前设置
            if let str = UserDefaults.standard.object(forKey: pp_const_AppLanguageKey) as? String, str != "default" {
                retValue = str
            }
            //PPLog("获取当前语言：\(retValue)")
            
            if retValue.hasPrefix(LanguageType.zh_Hans.rawValue){
                TimeAgo.manager.currentLanguage = LanguageType.zh_Hans.rawValue
            }else if retValue.hasPrefix(LanguageType.zh_Hant.rawValue){
                TimeAgo.manager.currentLanguage = LanguageType.zh_Hant.rawValue
            }else{
                TimeAgo.manager.currentLanguage = "en_US"
            }
            
            return retValue
        }
        
        set{
            UserDefaults.standard.set(newValue, forKey: pp_const_AppLanguageKey)
        }
    }
    
    //MARK: 实例化方法
    /**
     应用启动装载应用程序相关资源
     */
    func installApp() {
        
    }
    
    //MARK: DeviceToken KVO
    /// 推送的DeviceToken
    dynamic var pushToken:String = ""
    var obs_pushToken:NSKeyValueObservation?
    
    func initKVO(){
        obs_pushToken = observe(\.pushToken, options: [.old,.new], changeHandler: { [weak self] _, o in
            PPLog("pushToken: oldValue:\(o.oldValue) newValue:\(o.newValue)")
            if self?.isLogined == true {
                //XPNetworkApi.shared.user_bindDeviceToken()
            }else{
                if currentToken().isNotNullOrEmpty() {
                    //XPNetworkApi.shared.user_visitorTokenUpdate()
                }else{
                    //XPNetworkApi.shared.user_visitorLogin()
                }
            }
        })
    }
    
    //MARK: 用户信息登录登出
    /// 是否登录
    var isLogined: Bool {
        if loginUser != nil {
            //PPLog("有登录用户对象")
            return true
        }
        //PPLog("空登录用户对象")
        return false
    }
    /// 当前登录用户信息
    lazy var loginUser: XPBaseUser? = {
        guard let data = XPSandbox.shared.unarchiveObject(pp_archive_LoginUserFileName,true) as? Data else{
            //PPLog("没有登录用户信息归档数据")
            return nil
        }
        guard let dict = pp_json_fromData(data) else{
            //PPLog("转换登录用户信息出错")
            return nil
        }
        if let user:XPBaseUser = XPBaseUser.deserialize(from: dict) {
            //PPLog("有登录用户信息归档数据-返回")
            return user
        }
        //PPLog("登录用户信息归档数据-空")
        return nil
    }()
    
    /// 登录方式
    var loginType: LoginType {
        get {
            guard let str = UserDefaults.standard.value(forKey: pp_const_logintype) as? String else{
                return .unkown
            }
            return LoginType(rawValue: str)!
        }
        set {
            UserDefaults.standard.set(newValue.rawValue, forKey: pp_const_logintype)
        }
    }
    
    /// 保存用户信息
    /// - Parameter user: <#user description#>
    func saveUser(_ user:[String:Any]){
//        loginUser = XPBaseUser.deserialize(from: user)
//        //这里将后台返回的用户信息字段转换成 data存储
//        if let data = pp_json_toData(user) {
//            XPSandbox.shared.archiveObject(data, fileName: pp_archive_LoginUserFileName,true)
//        }
    }
    
    /// 更新用户信息
    /// - Parameter callBack: <#callBack description#>
    func updateUser(callBack: @escaping (_ isSuccess:Bool, _ msg:String?) -> Void){
        if !isLogined { return }
//        XPNetworkApi.shared.user_detail { (msg, count, res) in
//            callBack(true,msg)
//        } failed: {  (msg, code) in
//            callBack(false,msg)
//        }
    }
    
    /// 登录
    /// - Parameter user: <#user description#>
    func login(_ user:XPBaseUser) {
        
        //设置已经登录状态
        loginUser = user
        //loginType = user.loginType!
        
        //用户对象SSKeyChain
//        if user.loginType! == .byPassword {
//            let keychain = KeychainSwift()
//            keychain.set(user.password!, forKey: pp_AppKeychainNameKey)
//        }
        
        //绑定推送Token
        if pushToken.isNotNullOrEmpty() && isLogined{
            //XPNetworkApi.shared.user_bindDeviceToken()
        }
        
        //重新连接Socket
        //visitorInfo = nil
        //MTSocket.shared.disconnect()
        
        //游客数据同步合并登录用户、并同步服务器数据
        //MTFavoritesLogicMgr.shared.syncVisitorToUser()
        
        //发送登录状态通知
        NotificationCenter.default.post(name: .xpfLoginStatusChanged, object: nil)
    }
    
    /// 如果有登录失效情况的话需要实现这个方法，进行重新登录
    func relogin(){
        /*
         登录情况：手机验证码，用户名密码，微信，微博，QQ
         */
    }
    
    /**‘
     退出登录
     */
    func logout() {
        //设置登出状态通知,移除登录信息
        //XPSandbox.shared.removeFile(.archives, pp_archive_LoginUserFileName, true)
        
        loginUser = nil
        
        //服务器登录接口调用
        //[XPApiManager logout:nil failed:nil error:nil];
        
        //IM登出
        /*
         NIMSDK.shared().loginManager.logout { (error) in
         
         }
         */
        
        //移除别名
        /*
         JPUSHService.deleteAlias({ (iResCode, iAlias, seq) in
         
         }, seq: 0)
         */
        
        //删除本地SSKeyChain密码存储
        if loginType == .byPassword {
            let keychain = KeychainSwift()
            keychain.delete(pp_AppKeychainNameKey)
        }
        loginType = .unkown
        
        //取消第三方授权
        //ShareSDK.cancelAuthorize(.typeWechat, result: nil)
        //ShareSDK.cancelAuthorize(.typeQQ, result: nil)
        //ShareSDK.cancelAuthorize(.typeSinaWeibo, result: nil)
        //ShareSDK.cancelAuthorize(.typeAppleAccount, result: nil)
        
        //退出登录以后获取游客Token信息
        //XPNetworkApi.shared.user_visitorLogin()
        
        //断开Socket让其启动重连
        //MTSocket.shared.disconnect()
        
        //发送登录状态通知
        NotificationCenter.default.post(name: .xpfLoginStatusChanged, object: nil)
    }
}
